#include "scriptcreator.h"

#include <scripting/scriptenvironment.h>
#include <extensions/context.h>
#include <extensions/plugin.h>
#include <scripting/scripttask.h>
#include "wizard/classwizard.h"
#include "project.h"
#include "projectfolder.h"

class ScriptCreatorPrivate{
public:
	ScriptCreatorPrivate() {}
	~ScriptCreatorPrivate() {}
	QString curFile;
	QAction *runScript;

	enum { MaxRecentFiles = 5 };
	QAction *recentFileActs[MaxRecentFiles];
	Optra::Extensions::Context *context;

	Project* project;
};

ScriptCreator::ScriptCreator(Optra::Extensions::Context *context) :
        Optra::Extensions::MainWindow(0), O_PRIVATE_CREATE(ScriptCreator)
{
    O_D(ScriptCreator);
    d->context = context;
    setupUi(this);
    createActions();
    createMenus();
    (void)statusBar();
    setWindowFilePath(QString());
}

ScriptCreator::~ScriptCreator()
{
	O_PRIVATE_DELETE;
}
Project* project;
void ScriptCreator::newFile()
{
    O_D(ScriptCreator);
    //ScriptCreator *other = new ScriptCreator(0);
    //other->show();
    //ClassWizard* w = new ClassWizard(d->context);
    //w->show();

	QUrl u = QUrl::fromLocalFile("project.proj");
	qDebug() << u.toString() << " -> " << u.toLocalFile();
	project = new Project();
	project->setSource(u);
	project->setName("name #$%^");
	//project->create();

	ProjectFolder* fol = new ProjectFolder();
	fol->create();
	fol->setName("Folder 1");
	project->addItem(fol);

	ProjectFolder* fol2 = new ProjectFolder();
	fol2->create();
	fol2->setName("Folder 1.2");
	fol->addItem(fol2);

	fol2 = new ProjectFolder();
	fol2->create();
	fol2->setName("Folder 1.2");
	fol->addItem(fol2);

	ProjectFolder* fol3 = new ProjectFolder();
	fol3->create();
	fol3->setName("Folder 1.1.0");
	fol2->addItem(fol3);

	fol = new ProjectFolder();
	fol->setName("Folder 3");
	fol->create();
	project->addItem(fol);

	fol = new ProjectFolder();
	fol->setName("Folder 4");
	fol->create();
	project->addItem(fol);

	project->save();

	project = new Project();
	project->setSource(u);
	project->setName("name #$%^");
	//project->create();
	project->load();
	//project->widget()->setParent(frameMain);
	//project->widget()->geometry().setSize(frameMain->geometry().size());
	verticalLayout_2->addWidget(project->widget());
	frameMain->hide();
	verticalLayout_2->layout();
}

void ScriptCreator::open()
{
	ProjectFolder* fol = new ProjectFolder();
	fol->create();
	fol->setName("Folder");
	project->addItem(fol);

	ProjectFolder* fol2 = new ProjectFolder();
	fol2->create();
	fol2->setName("Folder2");
	fol->addItem(fol2);
	project->save();
	// 	fol = new ProjectFolder();
	// 	fol->setName("Folder");
	// 	fol->create();
	// 	project->addItem(fol);
	// 
	// 	fol = new ProjectFolder();
	// 	fol->setName("Folder");
	// 	fol->create();
	// 	project->addItem(fol);
//     QString fileName = QFileDialog::getOpenFileName(this);
//     if (!fileName.isEmpty())
//         loadFile(fileName);
}

void ScriptCreator::save()
{
    O_D(ScriptCreator);
    if (d->curFile.isEmpty())
        saveAs();
    else
        saveFile(d->curFile);
}

void ScriptCreator::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this);
    if (fileName.isEmpty())
        return;

    saveFile(fileName);
}

void ScriptCreator::openRecentFile()
{
    QAction *action = qobject_cast<QAction *>(sender());
    if (action)
        loadFile(action->data().toString());
}

void ScriptCreator::createActions()
{
    O_D(ScriptCreator);

    for (int i = 0; i < ScriptCreatorPrivate::MaxRecentFiles; ++i) {
        d->recentFileActs[i] = new QAction(this);
        d->recentFileActs[i]->setVisible(false);
        connect(d->recentFileActs[i], SIGNAL(triggered()),
                this, SLOT(openRecentFile()));
    }
}

void ScriptCreator::createMenus()
{
    O_D(ScriptCreator);
    for (int i = 0; i < ScriptCreatorPrivate::MaxRecentFiles; ++i)
        menuRecent_scripts->addAction(d->recentFileActs[i]);

    updateRecentFileActions();

}

void ScriptCreator::loadFile(const QString &fileName)
 {
    O_D(ScriptCreator);
     QFile file(fileName);
     if (!file.open(QFile::ReadOnly | QFile::Text)) {
         QMessageBox::warning(this, tr("Recent Files"),
                              tr("Cannot read file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
         return;
     }

     QTextStream in(&file);
     QApplication::setOverrideCursor(Qt::WaitCursor);
     QString data = in.readAll();
     textEdit->setPlainText(data);
     QApplication::restoreOverrideCursor();

     setCurrentFile(fileName);
     statusBar()->showMessage(tr("File loaded"), 2000);
 }

 void ScriptCreator::saveFile(const QString &fileName)
 {
     O_D(ScriptCreator);
     QFile file(fileName);
     if (!file.open(QFile::WriteOnly | QFile::Text)) {
         QMessageBox::warning(this, tr("Recent Files"),
                              tr("Cannot write file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
         return;
     }

     QTextStream out(&file);
     QApplication::setOverrideCursor(Qt::WaitCursor);
     out << textEdit->toPlainText();
     QApplication::restoreOverrideCursor();

     setCurrentFile(fileName);
     statusBar()->showMessage(tr("File saved"), 2000);
 }

 void ScriptCreator::setCurrentFile(const QString &fileName)
 {
     O_D(ScriptCreator);
     d->curFile = fileName;
     setWindowFilePath(d->curFile);

     QSettings settings;
     QStringList files = settings.value("recentFileList").toStringList();
     files.removeAll(fileName);
     files.prepend(fileName);
     while (files.size() > ScriptCreatorPrivate::MaxRecentFiles)
         files.removeLast();

     settings.setValue("recentFileList", files);

     foreach (QWidget *widget, QApplication::topLevelWidgets()) {
         ScriptCreator *mainWin = qobject_cast<ScriptCreator *>(widget);
         if (mainWin)
             mainWin->updateRecentFileActions();
     }
 }

 void ScriptCreator::updateRecentFileActions()
 {
     O_D(ScriptCreator);
     QSettings settings;
     QStringList files = settings.value("recentFileList").toStringList();

     int numRecentFiles = qMin(files.size(), (int)ScriptCreatorPrivate::MaxRecentFiles);

     for (int i = 0; i < numRecentFiles; ++i) {
         QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
         d->recentFileActs[i]->setText(text);
         d->recentFileActs[i]->setData(files[i]);
         d->recentFileActs[i]->setVisible(true);
     }
     for (int j = numRecentFiles; j < ScriptCreatorPrivate::MaxRecentFiles; ++j)
         d->recentFileActs[j]->setVisible(false);
 }

 QString ScriptCreator::strippedName(const QString &fullFileName)
 {
     return QFileInfo(fullFileName).fileName();

 }

 void ScriptCreator::output(const QString& str)
 {
    outputText->append(str);
 }

 void ScriptCreator::error(const QScriptValue & exception)
 {
    outputText->append("ERROR:" + exception.toString());
 }

void ScriptCreator::loadPlugin()
{
    O_D(ScriptCreator);
    save();

    outputText->clear();
    Optra::Extensions::Plugin* plg = d->context->loadPlugin(d->curFile);
    if (!plg->valid()) {
        outputText->append(plg->errorString());
        return;
    }

    plg->Start();
}

void ScriptCreator::runDeclarative()
{
    O_D(ScriptCreator);
    save();
    outputText->clear();
    //QObject* o = d->context->execQML(d->curFile, false);
//    if (!o) {
//        outputText->append("Error!");
//        return;
//    }
}

void ScriptCreator::run()
{
    O_D(ScriptCreator);
    outputText->clear();
    Opl::Scripting::ScriptEnvironment* sce = d->context->scripts();
    QString src = textEdit->toPlainText();
    connect(sce, SIGNAL(output(QString)), this, SLOT(output(QString)));
    connect(sce, SIGNAL(error(QScriptValue)), this, SLOT(error(QScriptValue)));
    d->context->start(new Opl::Scripting::ScriptTask(sce, src), true, "Developer Script");
}


